package com.nibianplus.volley.request;

import android.content.Context;
import android.content.SharedPreferences;

import com.android.volley.AuthFailureError;
import com.android.volley.NetworkResponse;
import com.android.volley.ParseError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.Response.ErrorListener;
import com.android.volley.Response.Listener;
import com.android.volley.toolbox.HttpHeaderParser;
import com.nibianplus.util.AppUtil;
import com.nibianplus.util.ContextUtil;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class CommonPostRequest extends Request<JSONObject>{

	
	private Map<String, Object> mParams;
//	private Map<String, String> mHeaders;
	private Listener<JSONObject> mListener;
	
	
	
	public CommonPostRequest(String url, Map<String, Object> map,Listener<JSONObject> listener,
			ErrorListener errorListener) {
		super(Request.Method.POST, url, errorListener);

		mParams = (map == null ? new HashMap<String, Object>() : map);
		mListener = listener;
	}
	
	
	@Override
	public Map<String, String> getHeaders() throws AuthFailureError {
		 Map<String, String> headers = new HashMap<String, String>();
		 SharedPreferences sp = ContextUtil.getContext()
				 .getSharedPreferences(AppUtil.getAppName(), Context.MODE_PRIVATE);
			String cookieStr = (String) sp.getString("cookie", "{}");
			JSONObject cookies;
			try {
				cookies = new JSONObject(cookieStr);
				
				if(cookies.length() >0){
					StringBuilder sb = new StringBuilder();
					 Iterator<String> itr = cookies.keys();
					for( ;itr.hasNext(); )
					{
						sb.append( itr.next() );
						sb.append(";");
					}
					sb.deleteCharAt(sb.length() - 1);
					
					headers.put("Cookie", sb.toString());
				}
			} catch (JSONException e) {
				e.printStackTrace();
			}
			
		
		//headers.put("Content-Type", "application/json");
		headers.put("Content-Type", "application/x-www-form-urlencoded");
		return headers;
	}
	
	@Override
	protected Map<String, Object> getParams() throws AuthFailureError {
		return mParams;
	}



	@Override
	protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
		String jsonString = "";
		try {
			jsonString = new String(response.data,
					HttpHeaderParser.parseCharset(response.headers));
			
			Map<String,List<String>> header = response.headers;
			
			List<String> cookieStrs = header.get("Set-Cookie");
			
			SharedPreferences sp = ContextUtil.getContext()
					 .getSharedPreferences(AppUtil.getAppName(), Context.MODE_PRIVATE);
			String savedCookies = (String) sp.getString("cookie", "{}");
			JSONObject cookies = new JSONObject(savedCookies);
			if(cookieStrs != null )
			{
				for( String cookieStr : cookieStrs )
				{
					String name = cookieStr.split(";")[0];
					cookies.put(name, cookieStr);
				}
				String cookieFromResponse = cookies.toString();
               	sp.edit().putString("cookie", cookieFromResponse).commit();
			}
			return Response.success(new JSONObject(jsonString),
					HttpHeaderParser.parseCacheHeaders(response));
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			return Response.error(new ParseError(e));
		} catch (JSONException je) {
			je.printStackTrace();
			try {
				//当解析错误的时候，将错误的json对象再封装成json对象返回，在封装之前替换掉错误的json对象中特殊字符（  [{}":  ）
				return Response.success(new JSONObject("{\"error\":\""+jsonString.replaceAll("[{}\":]", "?")+"\"}"),
						HttpHeaderParser.parseCacheHeaders(response));
			} catch (JSONException e) {
				e.printStackTrace();
				return Response.error(new ParseError(je));
			}
			//return Response.error(new ParseError(je));
		}
	}

	@Override
	public byte[] getBody() throws AuthFailureError 
	{
		if(getMethod() == Method.POST){
			StringBuilder encodedParams = new StringBuilder();
	        try {
	            for (Map.Entry<String, Object> entry : getParams().entrySet()) {
	                encodedParams.append(URLEncoder.encode(entry.getKey(), getParamsEncoding()));
	                encodedParams.append('=');
	                encodedParams.append(URLEncoder.encode(entry.getValue().toString(), getParamsEncoding()));
	                encodedParams.append('&');
	            }
	            encodedParams = encodedParams.deleteCharAt(encodedParams.length() - 1);
	            return encodedParams.toString().getBytes(getParamsEncoding());
	        } catch (UnsupportedEncodingException uee) {
	            throw new RuntimeException("Encoding not supported: " + getParamsEncoding(), uee);
	        }
		}
		else{
			return super.getBody();
		}
		
	}

	@Override
	protected void deliverResponse(JSONObject response) {
		mListener.onResponse(response);
	}
	
}
